using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using igp.net.DataModel;

namespace igp.net
{
	/// <summary>
	/// Represents a cursor that is used to indicate functions' values when moving mouse in Evaluate interaction mode.
	/// </summary>
	public class IgpEvaluationCursor : IgpItem
	{
		private IgpFunctionBase pointAt;
		
        /// <summary>
        /// Draws the cursor on the screen.
        /// </summary>
        /// <param name="graph">Graphics object used for drawing</param>
		public override void Draw(Graphics graph)
		{
			const int radius = 5;
            IgpView view = IgpProject.Singleton.View;
            
            Rectangle rec = new Rectangle(view.GetScreenCoordinateX(x)-radius,
				                          view.GetScreenCoordinateY(y)-radius,
				                          2*radius,
				                          2*radius
                                          );

            Rectangle rec2 = new Rectangle(view.GetScreenCoordinateX(x) - radius + 1,
                                           view.GetScreenCoordinateY(y) - radius + 1,
                                           2 * radius,
                                           2 * radius
                                           );

			graph.DrawEllipse(new Pen(Color.Black,1),rec2);
            graph.DrawEllipse(new Pen(Color.Red, 1), rec);

            string st = " [ " + x.ToString("0.0000") + " ; " + y.ToString("0.0000") + " ]";

            Point tp = new Point(
                Math.Min(Math.Max(25, view.GetScreenCoordinateX(x) - 30), 
                         view.Width - graph.MeasureString(st, igpSettings.Singleton.ChartFont).ToSize().Width - 5),
                Math.Min(Math.Max(view.GetScreenCoordinateY(y) - 30,5),
                         view.Height-25)
                         );

            Rectangle re = new Rectangle(tp, graph.MeasureString(st, igpSettings.Singleton.ChartFont).ToSize());
            Rectangle re2 = new Rectangle(new Point(tp.X + 3, tp.Y + 3), graph.MeasureString(st, igpSettings.Singleton.ChartFont).ToSize());

            graph.FillRectangle(new SolidBrush(Color.FromArgb(100, Color.Black)), re2);
            graph.FillRectangle(new LinearGradientBrush(re, Color.White, Color.FromArgb(230, 230, 230), 0, false), re);
            graph.DrawRectangle(new Pen(Color.DarkGray), re);
			graph.DrawString(st, igpSettings.Singleton.ChartFont,new SolidBrush(Color.Black),tp);
		}

        /// <summary>
        /// Forces the cursor to update.
        /// </summary>
        /// <param name="eX">x coordinate in pixels (screen coordinates)</param>
		public void Update(int eX)
		{
			switch ( FormMain.Singleton.EditorWindow.GetActivePage() )
			{
				case 3 : pointAt = IgpProject.Singleton.CurrentPolynomial; break;
				case 2 : pointAt = IgpProject.Singleton.CurrentFunction; break;
			}

			double tx = IgpProject.Singleton.View.GetRealCoordinateX(eX);
			
            if ((tx< pointAt.DomainLower || pointAt.DomainHigher < tx )
				&& pointAt.DomainHigher != pointAt.DomainLower ) return;
			
            x = tx;
            y = pointAt.Value(x);
		}

        /// <summary>
        /// Forces the cursor to update.
        /// </summary>
        /// <param name="tx">x coordinate in real coordinates</param>
		public void Update(double tx)
		{
			switch ( FormMain.Singleton.EditorWindow.GetActivePage() )
			{
				case 3 : pointAt = IgpProject.Singleton.CurrentPolynomial; break;
				case 2 : pointAt = IgpProject.Singleton.CurrentFunction; break;
			}

			if ((tx< pointAt.DomainLower || pointAt.DomainHigher < tx )
				&& pointAt.DomainHigher != pointAt.DomainLower ) return;
			
            x = tx;
			y = pointAt.Value(x);
		}

        /// <summary>
        /// This method is required for item's reaction to mouse movement. 
        /// You must invoke this base method in your derived class in order 
        /// to update some useful properties.
        /// </summary>
        /// <param name="graph">Graphics object that can be used to paint something on the screen</param>
        /// <param name="e">Mouse Event Details</param>
		public override void InteractMove(Graphics graph, System.Windows.Forms.MouseEventArgs e)
		{
			base.InteractMove (graph, e);
			Update(e.X);
			Draw(graph);
		}

		private double x;

		private double y;
	}
}
